package main

import (
	"context"
	"fmt"
	"strings"
	"time"
)

const KEY = "trace_id"

func NewRequestID() string {
	return strings.Replace("5E3D6415-64A1-473A-9EB3-03C3E6F3A291", "-", "", -1)
}

func NewContextWithTraceID() context.Context {
	ctx := context.WithValue(context.Background(), KEY, NewRequestID())
	return ctx
}

func PrintLog(ctx context.Context, message string) {
	fmt.Printf("%s|info|trace_id=%s|%s", time.Now().Format("2006-01-02 15:04:05"), GetContextValue(ctx, KEY), message)
}

func GetContextValue(ctx context.Context, k string) string {
	v, ok := ctx.Value(k).(string)
	if !ok {
		return ""
	}
	return v
}

func ProcessEnter(ctx context.Context) {
	PrintLog(ctx, "Goland梦工厂")
}

func NewContextWithTimeOut() (context.Context, context.CancelFunc) {
	return context.WithTimeout(context.Background(), 3*time.Second)
}

func HttpHandler() {
	ctx, cancel := NewContextWithTimeOut()
	defer cancel()
	//deal(ctx)

	dealWithCancel(ctx, cancel)
}

func deal(ctx context.Context) {
	for i := 0; i < 100; i++ {
		time.Sleep(1 * time.Second)
		select {
		case <-ctx.Done():
			fmt.Println("ctx到时间了")
			fmt.Println(ctx.Err())
			return

		default:
			fmt.Printf("deal time is %d\n", i)

		}

	}
}

func dealWithCancel(ctx context.Context, cancel context.CancelFunc) {
	for i := 0; i < 100; i++ {
		time.Sleep(1 * time.Second)
		select {
		case <-ctx.Done():
			fmt.Println("ctx到时间了")
			fmt.Println(ctx.Err())
			return

		default:
			fmt.Printf("deal time is %d\n", i)
			//cancel()
		}

	}
}

func Speak(ctx context.Context) {
	for range time.Tick(time.Second) {
		select {
		case <-ctx.Done():
			fmt.Println("我要闭嘴了")
			return
		default:
			fmt.Println("我一直在说话")
		}
	}
}

func main() {
	//ProcessEnter(NewContextWithTraceID())
	HttpHandler()
	//ctx, cancel := context.WithCancel(context.Background())
	//go Speak(ctx)
	//time.Sleep(10 * time.Second)
	//cancel()
	//time.Sleep(1 * time.Second)
}
